﻿//-----------------------------------------------------------------------
// <copyright file="InstallationStageFactory.cs" author="Artak Mkrtchyan">
//     Creative Commons - GNU General Public License (http://creativecommons.org/licenses/GPL/2.0/
// </copyright>
// <author>Artak Mkrtchyan</author>
// <email>mkArtak@gmail.com</email>
// <date>20/03/2013</date>

using AppUpdateInstaller.Model.InstallationStages;
using ConsoleHoster.Common.Utilities;
using ConsoleHoster.Common.Utilities.IO;
using System;
using System.ComponentModel;
using System.Linq;
using System.Windows;

namespace AppUpdateInstaller.Model
{
	public class InstallationStageFactory : IInstallationStageFactory
	{
		private readonly string[] args;
		private readonly IProcessManager processManager;
		private readonly IFileSystemContentProvider fileSystemContentProvider;
		private readonly Action appShutdownLogic;
		private readonly InstallerMode currentMode;

		public InstallationStageFactory(string[] args, IProcessManager argProcessManager, IFileSystemContentProvider argFileSystemContentProvider, Action argShutdownLogic)
		{
			if ((args == null || !args.Any()) && !DesignerProperties.GetIsInDesignMode(new DependencyObject()))
			{
				throw new ArgumentNullException("Improper startup parameters provided");
			}

			if (argProcessManager == null)
			{
				throw new ArgumentNullException("argProcessManager");
			}

			if (argFileSystemContentProvider == null)
			{
				throw new ArgumentNullException("argFileSystemContentProvider");
			}

			this.processManager = argProcessManager;
			this.fileSystemContentProvider = argFileSystemContentProvider;
			this.appShutdownLogic = argShutdownLogic;

			this.args = args.Select(item => item).ToArray();
			this.currentMode = this.GetCurrentMode();
		}

		public IInstallationStage Create()
		{
			IInstallationStage tmpStage = null;
			switch (this.currentMode)
			{
				case InstallerMode.ExtractArchive:
					tmpStage = new CompositeStage(new IInstallationStage[]{ 
						new ExtractPackageStage(args[1], args[2], this.processManager, this.fileSystemContentProvider, this.appShutdownLogic),
						new KeepNecessaryDataStage(args[1], args[2], this.processManager, this.fileSystemContentProvider, this.appShutdownLogic, new[]{"projects.xml"})
					});
					break;

				case InstallerMode.UpdateBinaries:
					tmpStage = new UpdateBinariesStage(args[1], args[2], this.fileSystemContentProvider, this.processManager, this.appShutdownLogic);
					break;

				case InstallerMode.CleanupUpdateBinaries:
					tmpStage = new RemoveUpdateFolderStage(args[1], args[2], this.fileSystemContentProvider, this.processManager, this.appShutdownLogic);
					break;
			}

			return tmpStage;
		}

		private InstallerMode GetCurrentMode()
		{
			InstallerMode tmpCurrentMode;

			int tmpIntValue;
			if (Int32.TryParse(this.args[0], out tmpIntValue))
			{
				throw new ArgumentException("Not supported installer type");
			}

			if (!Enum.TryParse<InstallerMode>(args[0], out tmpCurrentMode))
			{
				throw new ArgumentException(StringUtilities.Format("Invalid argument: '{0}'", args[0]));
			}
			return tmpCurrentMode;
		}
	}
}
